package ginx

import (
	"fmt"
	"net/http"
	"github.com/gin-gonic/gin"
)
type Result struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
	Data any    `json:"data"`
}

/*
	1. 通过使用以下方法，可减少重复代码量，提高可维护性
	例如：
     a. 未优化前的代码
		func (h *UserHandler) LoginJWT(ctx *gin.Context) {
			type Req struct {
				Email    string `json:"email"`
				Password string `json:"password"`
			}
			var req Req
			if err := ctx.Bind(&req); err != nil {
				return
			}
			u, err := h.svc.Login(ctx, req.Email, req.Password)
			switch err {
			case nil:
				uc := UserClaims{
					Uid: u.Id,
					RegisteredClaims: jwt.RegisteredClaims{
						// 1 分钟过期
						ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Minute)),
					},
				}
				token := jwt.NewWithClaims(jwt.SigningMethodHS512, uc)
				tokenStr, err := token.SignedString(JWTKey)
				if err != nil {
					ctx.String(http.StatusOK, "系统错误")
				}
				ctx.Header("x-jwt-token", tokenStr)
				ctx.String(http.StatusOK, "登录成功")
			case service.ErrInvalidUserOrPassword:
				ctx.String(http.StatusOK, "用户名或者密码不对")
			default:
				ctx.String(http.StatusOK, "系统错误")
			}
		}

	b. 优化后的代码
		func (h *UserHandler) LoginJWT(ctx *gin.Context, req LoginJWTReq) (ginx.Result, error) {
			u, err := h.svc.Login(ctx, req.Email, req.Password)
			switch err {
			case nil:
				err = h.SetLoginToken(ctx, u.Id)
				if err != nil {
					return ginx.Result{
						Code: 5,
						Msg:  "系统错误",
					}, err
				}
				return ginx.Result{
					Msg: "OK",
				}, nil
			case service.ErrInvalidUserOrPassword:
				return ginx.Result{Msg: "用户名或者密码错误"}, nil
			default:
				return ginx.Result{Msg: "系统错误"}, err
			}
		}

*/
func WrapBody[Req any]( bizFn func(ctx *gin.Context, req Req) (Result, error), ) gin.HandlerFunc {
	return func(ctx *gin.Context) {
		var req Req
		if err := ctx.Bind(&req); err != nil {
			fmt.Errorf("输入错误:%v\n", err)
			return
		}
		fmt.Printf("输入参数:%v\n",req)
		res, err := bizFn(ctx, req)
		if err != nil {
			fmt.Errorf("执行业务逻辑失败:%v\n", err)
		}
		ctx.JSON(http.StatusOK, res)
	}
}
